﻿using System;

class OrderDetails
{
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public double UnitPrice { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is OrderDetails other)
        {
            return ProductName == other.ProductName;
        }
        return false;
    }

    public override string ToString()
    {
        return $"Product: {ProductName}, Quantity: {Quantity}, Unit Price: {UnitPrice}";
    }
}

class Order
{
    public int OrderId { get; set; }
    public string Customer { get; set; }
    public List<OrderDetails> Details { get; set; }
    public double TotalAmount => Details.Sum(detail => detail.Quantity * detail.UnitPrice);

    public override bool Equals(object obj)
    {
        if (obj is Order other)
        {
            return OrderId == other.OrderId;
        }
        return false;
    }

    public override string ToString()
    {
        return $"Order ID: {OrderId}, Customer: {Customer}, Total Amount: {TotalAmount}";
    }
}

class OrderService
{
    private List<Order> orders = new List<Order>();

    public void AddOrder(Order order)
    {
        if (orders.Contains(order))
        {
            throw new InvalidOperationException("Order already exists.");
        }

        orders.Add(order);
    }

    public void RemoveOrder(int orderId)
    {
        Order orderToRemove = orders.FirstOrDefault(order => order.OrderId == orderId);
        if (orderToRemove == null)
        {
            throw new InvalidOperationException("Order not found.");
        }

        orders.Remove(orderToRemove);
    }

    public void UpdateOrder(Order updatedOrder)
    {
        Order existingOrder = orders.FirstOrDefault(order => order.OrderId == updatedOrder.OrderId);
        if (existingOrder == null)
        {
            throw new InvalidOperationException("Order not found.");
        }

        orders.Remove(existingOrder);
        orders.Add(updatedOrder);
    }

    public IEnumerable<Order> QueryOrders(Func<Order, bool> predicate)
    {
        return orders.Where(predicate).OrderBy(order => order.TotalAmount);
    }

    public void SortOrders(Func<Order, object> keySelector)
    {
        orders = orders.OrderBy(keySelector).ToList();
    }
}

class Program
{
    static void Main(string[] args)
    {
        OrderService orderService = new OrderService();

        Order order1 = new Order { OrderId = 1, Customer = "Alice", Details = new List<OrderDetails> { new OrderDetails { ProductName = "ProductA", Quantity = 2, UnitPrice = 10.5 } } };
        Order order2 = new Order { OrderId = 2, Customer = "Bob", Details = new List<OrderDetails> { new OrderDetails { ProductName = "ProductB", Quantity = 3, UnitPrice = 8.0 } } };
        orderService.AddOrder(order1);
        orderService.AddOrder(order2);

        var queryResults = orderService.QueryOrders(order => order.Customer == "Alice");
        foreach (var result in queryResults)
        {
            Console.WriteLine(result);
        }

        try
        {
            orderService.RemoveOrder(1);
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine(ex.Message);
        }

        Order updatedOrder = new Order { OrderId = 2, Customer = "Bob", Details = new List<OrderDetails> { new OrderDetails { ProductName = "ProductC", Quantity = 1, UnitPrice = 15.0 } } };
        try
        {
            orderService.UpdateOrder(updatedOrder);
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine(ex.Message);
        }

        orderService.SortOrders(order => order.OrderId);

        foreach (var order in orderService.QueryOrders(order => true))
        {
            Console.WriteLine(order);
        }
    }
}
